package splitter;

use strict;
use File::Copy;
use MP3::Info qw(:DEFAULT :genres);

use vars qw($VERSION);

$VERSION = '0.01';

sub new 
{
    my $package = shift;

    my  $self = {};

    $self->{cmds} = [];
    $self->{edits} = ();
    $self->{oldnames} = [];
    $self->{newnames} = [];
    $self->{scriptlines} = ();
    $self->{scriptminutes} = 0;
    $self->{mp3minutes} = 0;
    $self->{tags} = [];

    return(bless($self, $package));
}

sub prep
{
    my ($self, $scriptname, @inmp3list) = @_;

    $self->{cmds} = [];
    $self->{edits} = ();
    $self->{scriptlines} = ();
    $self->{scriptminutes} = 0;
    $self->{oldnames} = [];
    $self->{newnames} = [];
    $self->{tags} = [];
    $self->{innames} = [];

    my  $nextidx = 0;
    my  $mp3remain = 0;
    my  $inmp3 = '';
    my  ($artist, $album, $song, $trackminutes, $trackseconds)  = ('', '', '', 0, 0);
    my  $partPrefix = '';
    my  @parts = ();
    my $minutesNeeded = 0;
    my  $sofar = 0;
    my  $partno = 1;
    my  $partPostfix = '.mp3';
    my  $fileidx = 0;
    my  $outPrefix = 'Start';
    my  @frommp3 = ();

    open INF, "<$scriptname" or die "unable to open $scriptname for reading";

    while (<INF>)
    {
        if (/^\s*(walk|run|jog|finished)\s+([0-9\.]+)/i)
        {
            my  $action = $1;
            my  $minutes = $2;
            my  $secs = ($minutes * 60);
            my  $actionOut = 0;

            push @parts, "$action.mp3";

            while ($secs > 0)
            {
                my  $tocopy = min($secs, $mp3remain);

                if (($tocopy == 0) && ($nextidx <= $#inmp3list))
                {
                    $self->dumpCmd($inmp3);

                    $inmp3 = $inmp3list[$nextidx];
                    ++$nextidx;

                    my $info = MP3::Info->new($inmp3);

                    if (! defined($info))
                    {
                        die "$nextidx: no info for $inmp3\n";
                    }

                    ($artist, $album, $song, $trackminutes, $trackseconds) = ($info->artist, $info->album, $info->title, $info->mm, $info->ss);

                    $self->{mp3minutes} += $trackminutes;
                    $mp3remain = ($trackminutes * 60) + $trackseconds;
                    $sofar = 0;
                    $tocopy = min($secs, $mp3remain);
                    $partno = 1;

                    $partPrefix = $inmp3;

                    if ($partPrefix =~ /^(.+)\.mp3$/i)
                    {
                        $partPrefix = $1;
                    }

                    $outPrefix = $partPrefix;
                    $partPrefix .= "_";

                }

                if (! $actionOut)
                {
                    push @frommp3, $inmp3;
                    push @{ $self->{newnames} }, sprintf("%02i - %s%s", scalar @parts, $outPrefix, $partPostfix);
                    $actionOut = 1;
                }

                if ($tocopy == 0)
                {
                    last;
                }

                push @parts, "$partPrefix$partno$partPostfix";
                push @frommp3, $inmp3;
                push @{ $self->{newnames} }, sprintf("%02i - %s%s", scalar @parts, $outPrefix, $partPostfix);

                if ($tocopy >= $mp3remain)
                {
                    push @{ $self->{edits} }, "-e$sofar-";
                }
                else
                {
                    push @{ $self->{edits} }, "-e$sofar-" . ($sofar + $secs);
                }

                $mp3remain -= $tocopy;

                $sofar += $tocopy;
                ++$partno;
                $secs -= $tocopy;

                $minutesNeeded += $minutes;
            }

        }
    }

    close INF;

    push @{ $self->{edits} }, "-e$sofar-";
    push @parts, "finished.mp3";
    push @frommp3, $inmp3;

    push @{ $self->{newnames} }, sprintf("%02i - %s%s", scalar @parts, $outPrefix, $partPostfix);
    push @parts, "$partPrefix$partno$partPostfix";
    push @frommp3, $inmp3;

    push @{ $self->{newnames} }, sprintf("%02i - %s%s", scalar @parts, $outPrefix, $partPostfix);
    
    $self->{scriptminutes} = $minutesNeeded;
    $self->{oldnames} = \@parts;
    $self->dumpCmd($inmp3);
    
    for (my $i = 1; $i <= @parts; ++$i)
    {
        my  $fromfn = $frommp3[$i - 1];

        my  $info = MP3::Info->new($fromfn);

        if (! defined($info))
        {
            die "no info for $fromfn\n";
        }

        ($artist, $album, $song) = ($info->artist, $info->album, $info->title);

        my  $tag = {};
        $tag->{artist} = $artist;
        $tag->{album}  = $album;
        $tag->{title}  = sprintf("%02i - %s", $i, $song);

        push @{ $self->{tags} }, $tag;
    }

    $self->{innames} = \@frommp3;
}

sub dumpCmd
{
    my ($self, $inmp3) = @_;

    if ($inmp3 ne '')
    {
        #my  $cmd = 'mpgedit ' . join(' ', @{ $self->{edits} }) . " $inmp3";
       my $cmdList = ["mpgedit", @{ $self->{edits} }, $inmp3];

        print "-- pushing " . join(' ', @{ $cmdList } ) . "\n";

        push @{ $self->{cmds} }, $cmdList;
    }

    $self->{edits} = [];
}

sub enough
{
    my ($self) = @_;

    return( $self->{scriptminutes} <= $self->{mp3minutes} );
}

sub cmds
{
    my ($self) = @_;

    return( @{ $self->{cmds} } );
}

sub oldNames
{
    my ($self) = @_;

    return( @{ $self->{oldnames} } );
}

sub newNames
{
    my ($self) = @_;

    return( @{ $self->{newnames} } );
}

sub shouldMove
{
    my ($self, $fn) = @_;

    return($fn !~ /^(walk|run|jog|finished)\.mp3/i);

}


sub edit
{
    my ($self) = @_;

    my   @cmds = @{ $self->{cmds} };

    foreach my $cmd (@cmds)
    {
       my @cmdlist = @{ $cmd };

       print "-- path: " . join(' ', $ENV{'PATH'}) . "\n";

        my $ecode = system(@cmdlist);

        if ($ecode != 0)
        {      
            die join(' ', @cmdlist) . ":\nsystem call failed: $!\n";
        }
    }
}


sub moves
{
    my ($self) = @_;
    my  @oldnames = $self->oldNames();
    my  @newnames = $self->newNames();
    my  @tags = $self->tags();

    for (my $i = 0; $i < @oldnames; ++$i)
    {
        my  ($from, $to) = ($oldnames[$i], $newnames[$i]);

        if ($self->shouldMove($from))
        {
            print "renaming \"$from\" to \"$to\"\n";

            rename $from, $to or die "unable to rename $from to $to";
        }
        else
        {
            print "copying  \"$from\" to \"$to\"\n";

            copy($from, $to) or die "unable to copy $from to $to";
        }

        my  $tag = $tags[$i];

        $self->setTag($self->{innames}[$i], $to, $tag->{artist}, $tag->{album}, $tag->{title});
    }
}


sub setTag
{
   my ($self, $orig, $fname, $artist, $album, $title) = @_;

   my $tag = get_mp3tag($orig) or die "No tag info in $orig";

   my $genre = $tag->{GENRE};

   if (! defined($mp3_genres{$genre}))
   {
      $genre = "";
   }

   $tag->{COMMENT} = substr($tag->{COMMENT}, 0, 28);

#   if (! $pretend)
   #{
      $tag->{TITLE} = substr($title, 0, 30);
      $tag->{ARTIST} = $artist;
      $tag->{ALBUM}  = $album;
      $tag->{GENRE}  = $genre;

      set_mp3tag($fname, $tag);
   #}
}


sub scriptMinutes
{
    my ($self) = @_;

    return($self->{scriptminutes});
}

sub mp3Minutes
{
    my ($self) = @_;

    return($self->{mp3minutes});
}


sub tags
{
    my ($self) = @_;

    return( @{ $self->{tags} } );
}


sub min
{
    my ($a, $b) = @_;

    return($a <= $b ? $a : $b);
}

1;

